﻿using System;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcTemplates
{
    public class AutoCompleteAttribute : HtmlAttributesAttribute
    {
        public AutoCompleteAttribute( string source )
        {
            Source = source;
        }

        public AutoCompleteAttribute( string action, string controller = null )
        {
            Action = action;
            Controller = controller;
        }

        public string Source { get; private set; }        

        public string Action { get; private set; }

        public string Controller { get; set; }
        public string Area { get; set; }

        /// <summary>
        /// value used to indicate that the Source parameter is a javascript Array object and NOT a url.
        /// </summary>
        public bool SourceIsAnArray { get; set; }

        #region Options


        private bool? _disabled;
        private int? _delay;
        private int? _minLength;

        /// <summary>
        /// Disables the autocomplete
        /// </summary>
        public bool Disabled
        {
            get { return _disabled.GetValueOrDefault(); }
            set { _disabled = value; }
        }

        /// <summary>
        /// A specific selector to append the menu to.
        /// </summary>
        public string AppendTo { get; set; }

        /// <summary>
        /// The delay between the last key up event and when the search is triggered.
        /// </summary>
        public int Delay
        {
            get { return _delay.GetValueOrDefault(); }
            set { _delay = value; }
        }

        /// <summary>
        /// The minimum length before the search is triggered.
        /// </summary>
        public int MinLength
        {
            get { return _minLength.GetValueOrDefault(); }
            set { _minLength = value; }
        }        
        
        //events
        public string Create { get; set; }
        public string Search { get; set; }
        public string Open { get; set; }
        public string Focus { get; set; }
        public string Select { get; set; }        
        public string Close { get; set; }
        public string Change { get; set; }

        #endregion

        public override void Process( ModelMetadata modelMetadata )
        {
            modelMetadata.TemplateHint = "AutoComplete";
        }

        public MvcHtmlString RenderJavascript( UrlHelper urlHelper, HtmlHelper htmlHelper )
        {
            var output = new StringBuilder();
            string source;
    
            if ( Source != null )
            {
                source = Source;
            }
            else
            {
                var rvd = new RouteValueDictionary();
                rvd["action"] = Action;
                if ( !string.IsNullOrEmpty( Controller ) ){
                    rvd["controller"] = Controller;   
                }
                if ( !string.IsNullOrEmpty( Area ) ) {
                    rvd["area"] = Area;   
                }
                source = urlHelper.RouteUrl( rvd );
            }

            var id = GetIdOrNull() ?? htmlHelper.ViewData.TemplateInfo.GetFullHtmlFieldId( "" );


            output.Append( "$(document).ready(function(){\n\t\t" );
            output.AppendFormat( "$(\"#{0}\").autocomplete( {{\n\t\t\t", id );
            output.AppendFormat( "source: {0}{1}{0}", SourceIsAnArray ? "" : "\"", source );

            AppendOptionIf( _disabled.HasValue, "disabled", _disabled.ToString().ToLower(), output );
            AppendOptionIf( !string.IsNullOrEmpty( AppendTo ), "appendTo", string.Format( "\"{0}\"", AppendTo ), output );
            AppendOptionIf( _delay.HasValue, "delay", _delay.ToString(), output );
            AppendOptionIf( _minLength.HasValue, "minLength", _minLength.ToString(), output );
            AppendOptionIf( !string.IsNullOrEmpty( Create ), "create", Create, output );
            AppendOptionIf( !string.IsNullOrEmpty( Search ), "search", Search, output );
            AppendOptionIf( !string.IsNullOrEmpty( Open ), "open", Open, output );
            AppendOptionIf( !string.IsNullOrEmpty( Focus ), "focus", Focus, output );
            AppendOptionIf( !string.IsNullOrEmpty( Select ), "select", Select, output );
            AppendOptionIf( !string.IsNullOrEmpty( Close ), "close", Close, output );
            AppendOptionIf( !string.IsNullOrEmpty( Change ), "change", Change, output );

            output.Append( "\n\t\t} );\n\t " );            
            output.Append( "});" );
            return MvcHtmlString.Create( output.ToString() );
        }

        private void AppendOptionIf( bool test, string optionName, string value, StringBuilder output )
        {
            if ( test )
            {
                output.AppendFormat( ",\n\t\t\t{0}: {1}", optionName, value );
            }
        }
    }
}
